package com.yonyou.brigade.third_parties.smectrip.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.brigade.basic_init.enums.ChannelEnum;
import com.yonyou.brigade.basic_init.model.BriChannel;
import com.yonyou.brigade.basic_init.service.IBaseDocService;
import com.yonyou.brigade.basic_init.service.IBriChannelService;
import com.yonyou.brigade.basic_init.service.IUserCenterService;
import com.yonyou.brigade.third_parties.smectrip.constants.SmeCtripConstants;
import com.yonyou.brigade.third_parties.smectrip.model.CtripSmeUser;
import com.yonyou.brigade.third_parties.smectrip.service.ISmeCtripPublicService;
import com.yonyou.brigade.third_parties.smectrip.util.SmeCompanyRegisterError;
import com.yonyou.brigade.third_parties.smectrip.util.SmeCtripUtil;
import com.yonyou.brigade.util.HttpClientUtil;
import com.yonyou.brigade.util.operateutil.MD5Util;
import com.yonyou.brigade.util.operateutil.RedisUtils;
import com.yonyou.brigade.util.resultutil.HttpSendUtils;
import com.yonyou.iuap.ml.MultiLangContext;
import com.yonyou.ybzboot.starter.common.exception.BusinessException;
import com.yonyou.ybzboot.starter.common.exception.CustomException;
import com.yonyou.ybzboot.starter.common.util.StringUtil;
import com.yonyou.ybzboot.uc.dto.UcUserDto;
import corp.openapicalls.contract.setapproval.request.ExtendField;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * Created by Administrator on 2018/12/25.
 */
@Service
public class SmeCtripPublicServiceImpl implements ISmeCtripPublicService {

    @Autowired
    private SmeCtripUtil smeCtripUtil;

    @Autowired
    @Qualifier("briChannelServiceImpl")
    private IBriChannelService briChannelService;

    @Autowired
    @Qualifier("userCenterServiceImpl")
    private IUserCenterService iUserCenterService;

    @Value("${smectrip.url}")
    private String URL;

    @Value("${smectrip.autoRegisterCompanyUrl}")
    private String AUTO_REGISTER_COMPANY_URL;

    @Value("${smectrip.platformid}")
    private String CTRIP_SME_PLATFORMID;

    @Value("${smectrip.platformsn}")
    private String CTRIP_SME_PLATFORMSN;

    @Autowired
    private RedisUtils redisUtils;


    @Autowired
    private IBaseDocService baseDocService;

    private static final Logger logger = LoggerFactory.getLogger(SmeCtripPublicServiceImpl.class);

    @Override
    public boolean syncCtripSmeUsers(String tenantid, JSONArray memberInfoModelArray, String config) {
        JSONObject setMemberRequestModel = new JSONObject();
        JSONObject jsonObject = JSON.parseObject(config);
        if (jsonObject != null) {
            setMemberRequestModel.put("IsRunRealTime", true);
            setMemberRequestModel.put("AppKey", jsonObject.getString("appKey"));
            setMemberRequestModel.put("Ticket", smeCtripUtil.getBusinessTicket(tenantid, jsonObject.getString("appKey"), jsonObject.getString("appSecurity")));
            setMemberRequestModel.put("Version", 1.0);
        }
        setMemberRequestModel.put("Members", memberInfoModelArray);

        logger.info("同步人员请求->" + setMemberRequestModel.toJSONString());
        String resp = HttpSendUtils.sendPost(URL + SmeCtripConstants.SAVEMEMBER_URL, setMemberRequestModel.toJSONString());
        logger.info("同步人员返回值->" + resp);
        JSONObject respJSON = JSON.parseObject(resp);
        boolean success = respJSON.getBoolean("Success");
        int errorCode = respJSON.getIntValue("ErrorCode");
        boolean flag = false;
        if (success) {
            logger.info("同步人员成功");
            flag = true;
        } else {
            logger.error("参数验证失败,errorcode=" + errorCode);
            logger.error(respJSON.getString("Message"));
        }
        return flag;
    }

    @Override
    public String ssoLogin(CtripSmeUser ctripSmeUsers, HttpServletResponse
            response, String config, String initPage, String source) throws IOException {
        JSONObject jsonObject = JSON.parseObject(config);
        // Ticket 获取 URL
        //携程提供
        String appKey = jsonObject.getString("appKey");
        String appSecurity = jsonObject.getString("appSecurity");
        String ctripCorpId = jsonObject.getString("ctripCorpId");
        String employeeId = ctripSmeUsers.getEmployeeId();
        //不需要自动开卡
        int tokenType = 0;

        //获取 Ticket
        String token = smeCtripUtil.getLoginTicket(appKey, appSecurity, tokenType);

        String responseText = null;
        if ("pc".equalsIgnoreCase(source)) {
            //签名
            String signature = MD5Util.getMD5_32(appKey + employeeId + "0" + MD5Util.getMD5_32(appSecurity));

            responseText = "<html>\n";
            responseText += "<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">";
            responseText = responseText + "<script type=\"text/javascript\">function formSubmit(){document.getElementById(\"fLogin\").submit();}</script>";
            responseText = responseText + "</head><body>";
            responseText = responseText + "<form name=\"fLogin\" id=\"fLogin\" method=\"post\" action=\"" + URL + SmeCtripConstants.LOGIN_PC_URL + "\">";
            responseText = responseText + "<input type=\"hidden\" name=\"AppKey\" value=\"" + appKey + "\" />";
            responseText = responseText + "<input type=\"hidden\" name=\"Ticket\" value=\"" + token + "\" />";
            responseText = responseText + "<input type=\"hidden\" name=\"EmployeeID\" value=\"" + employeeId + "\"/>";
            responseText = responseText + "<input type=\"hidden\" name=\"Signature\" value=\"" + signature + "\"/>";
            responseText = responseText + "<input type=\"hidden\" name=\"TA\" value=\"\"/>";
            if (ctripSmeUsers.getaManager()) {
                responseText = responseText + "<input type=\"hidden\" name=\"Backurl\" value=\"https://ct.ctrip.com/platform/home/index\"/>";
            }
            responseText = responseText + "<script language=\"javascript\">formSubmit();</script></form></body>";
            responseText = responseText + "</html>";
            //设置编码为UTF-8
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            PrintWriter pw = response.getWriter();
            pw.println(responseText);

        } else {
            String signature = MD5Util.getMD5_32(appKey + employeeId + "public" + MD5Util.getMD5_32(appSecurity));
            responseText = "<html>\n" +
                    "<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" >\n" +
                    "<script type=\"text/javascript\">function formSubmit(){document.getElementById(\"fLogin\").submit();}</script>\n" +
                    "</head>\n" +
                    "<body>\n" +
                    "<form name=\"fLogin\" id=\"fLogin\" action=\"" + URL + SmeCtripConstants.LOGIN_H5_URL + "\" method=\"post\">\n" +
                    "<input type=\"hidden\" name=\"accessuserid\" value=\"" + appKey + "\" />\n" +
                    "<input type=\"hidden\" name=\"employeeid\" value=\"" + employeeId + "\" />\n" +
                    "<input type=\"hidden\" name=\"initpage\" value=\"" + initPage + "\"/>\n" +
                    "<input type=\"hidden\" name=\"appid\" value=\"" + ctripCorpId + "\" />\n" +
                    "<input type=\"hidden\" name=\"signature\" value=\"" + signature + "\" />" +
                    "<input type=\"hidden\" name=\"endorsementID\" value=\"\" />\n" +
                    "<input type=\"hidden\" name=\"token\" value=\"" + token + "\"/>\n" +
                    "<input type=\"hidden\" name=\"channel\" value=\"\"/>\n" +
                    "<input type=\"hidden\" name=\"OnError\" value=\"ErrorCode\"/>\n" +
                    "<input type=\"hidden\" name=\"Callback\" value=\"https://ct.ctrip.com/m\"/>\n" +
                    "<script language=\"javascript\">formSubmit();</script>\n" +
                    "</form>\n" +
                    "</body>\n" +
                    "</html>";
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            PrintWriter pw = response.getWriter();
            pw.println(responseText);
        }
        return responseText;
    }


    /**
     * 中小企业 自助开通携程服务 注册公司
     *
     * @param companyCode  目前取租户ID
     * @param companyName  目前取租户名
     * @param isPreApprove 是否提前审批
     * @return <code>String</code>
     */
    @Override
    public JSONObject autoRegisterCompany(String companyCode, String companyName, Integer isPreApprove) {
        List<BriChannel> briChannelList1 = briChannelService.getEnableChannelByTenantAndChannel(companyCode, ChannelEnum.CTRIPSME.getName());
        if (!CollectionUtils.isEmpty(briChannelList1)) {
            throw new CustomException("该租户已开通携程商旅通服务");
        }
        List<BriChannel> briChannelList2 = briChannelService.getEnableChannelByTenantAndChannel(companyCode, ChannelEnum.CTRIPBC.getName());
        if (!CollectionUtils.isEmpty(briChannelList2)) {
            throw new CustomException("该租户已开通携程大客户商旅服务");
        }

        JSONObject paramJson = new JSONObject();
        paramJson.put("PlatformId", CTRIP_SME_PLATFORMID);
        paramJson.put("PlatformSN", CTRIP_SME_PLATFORMSN);
        paramJson.put("company", companyCode);
        paramJson.put("companyName", companyName);
        paramJson.put("AuthorizeType", isPreApprove);
        logger.info("携程商旅通注册公司，请求数据->" + paramJson.toJSONString());
        String respStr = HttpClientUtil.doPostJson(AUTO_REGISTER_COMPANY_URL, paramJson.toJSONString());
        logger.info("携程商旅通注册公司，返回数据->" + respStr);

        JSONObject respJson = null;
        try {
            respJson = JSON.parseObject(respStr);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new CustomException(respStr);
        }

        if (!respJson.getBoolean("Success")) {
            logger.error("携程商旅通调用异常: " + respJson.getString("Message"));
            throw new RuntimeException("携程商旅通调用异常: " + respJson.getString("Message"));
        }
        if (respJson.getLongValue("ErrorCode") != 0) {
            logger.error("携程商旅通调用异常: " + SmeCompanyRegisterError.errorCodeMapping(respJson.getString("ErrorCode")));
            throw new RuntimeException("携程商旅通调用异常: " + SmeCompanyRegisterError.errorCodeMapping(respJson.getString("ErrorCode")));
        }
        //获取 Ticket
        JSONObject result = new JSONObject();
        result.put("appKey", respJson.getString("AppKey"));
        result.put("appSecurity", respJson.getString("AppSecurity"));
        result.put("ctripCorpID", respJson.getString("CtripCorpID"));
        return result;
    }

    @Override
    public String getSetApprovalTicket(BriChannel channel) throws IOException {
        JSONObject config = JSONObject.parseObject(channel.getConfig());
        //先从Redis中取，如果没有调接口
        String ticket = redisUtils.getValue("SME_SETAPPROVAL_TICKET" + channel.getTenant());
        if (StringUtil.isEmpty(ticket)) {
            JSONObject paramJson = new JSONObject();
            paramJson.put("appKey", config.getString("appKey"));
            paramJson.put("appSecurity", config.getString("appSecurity"));

            logger.info("携程商旅通，出差申请单同步ticket请求参数->" + paramJson.toJSONString());
            String respStr = Request.Post(SmeCtripConstants.SETAPPROVAL_TICKET_URL)
                    .bodyString(paramJson.toJSONString(), ContentType.APPLICATION_JSON)
                    .connectTimeout(60000).socketTimeout(60000)
                    .execute().returnContent().asString(Charset.forName("UTF-8"));
            logger.info("携程商旅通，出差申请单同步ticket返回参数->" + respStr);

            JSONObject respJson = null;
            try {
                respJson = JSON.parseObject(respStr);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new CustomException("1", respStr);
            }
            JSONObject status = respJson.getJSONObject("TicketResult");
            JSONObject statusJson = status.getJSONObject("Status");
            boolean success = statusJson.getBoolean("Success");
            if (!success) {
                String message = statusJson.getString("Message");
                logger.error("获取ticket失败->" + message);
                throw new CustomException("1", MultiLangContext.getInstance().getMessage("bz.other.getticketFail", new Object[]{message}));
            }
            //获取 Ticket
            ticket = status.getString("Ticket");
            //Redis中放两个小时
            redisUtils.setKey("SME_SETAPPROVAL_TICKET" + channel.getTenant(), ticket, 2 * 60);
        }
        return ticket;
    }

    @Override
    public JSONObject pushApplayOrder(BriChannel channel, String tenant, String orgpk, JSONObject applyOrderJson) {
        JSONObject summaryResult = new JSONObject();
        logger.info("携程商旅通申请单信息:" + applyOrderJson.toString());
        logger.info("开始拼装同步申请单数据");
        JSONObject data = processApplyData(applyOrderJson, tenant, channel);

        if (data.getString("msg") != null && !"".equals(data.getString("msg"))) {
            summaryResult.put("success", false);
            summaryResult.put("msg", data.getString("msg"));
            if (data.getBooleanValue("needUpdate")) {
                summaryResult.put("success", true);
            }
            return summaryResult;
        }

        JSONObject request = new JSONObject();
        request.put("request", data);
        logger.info("出差申请单同步请求json->" + request.toJSONString());

        String respStr = "";
        try {
            respStr = Request.Post(SmeCtripConstants.SETAPPROVAL_ACTION_URL)
                    .bodyString(request.toJSONString(), ContentType.APPLICATION_JSON)
                    .connectTimeout(60000).socketTimeout(60000)
                    .execute().returnContent().asString(Charset.forName("UTF-8"));
        } catch (Exception e) {
            summaryResult.put("success", false);
            summaryResult.put("msg", "推送携程商旅通失败 IO异常:" + e.getStackTrace());
            return summaryResult;
        }
        logger.info("申请单同步响应json->" + respStr);
        JSONObject respJson = JSONObject.parseObject(respStr);
        summaryResult.put("success", false);
        if (respJson != null) {
            JSONObject resultJson = respJson.getJSONObject("SetApprovalResult");
            JSONObject statusJson = resultJson.getJSONObject("Status");
            if (!statusJson.getBoolean("Success")) {
                String message = statusJson.getString("Message");
                logger.error("sme申请单同步失败->" + message);
                summaryResult.put("msg", "sme申请单同步失败->" + message);
            } else {
                summaryResult.put("success", true);
                logger.info("携程商旅通同步出差申请单成功");
            }
        }

        return summaryResult;
    }

    @Override
    public List closeApplyOrder( BriChannel channel ,JSONObject trip) {
        logger.info("开始拼装申请单数据");
        JSONObject data = processApplyData(trip, channel.getTenant(), channel);
        JSONArray result = new JSONArray();
        JSONObject res = new JSONObject();

        if (data.getString("msg") != null && !"".equals(data.getString("msg"))) {
            res.put("success", false);
            res.put("msg", data.getString("msg"));
            if (data.getBooleanValue("needUpdate")) {
                res.put("success", true);
            }
            result.add(res);
            return result;
        }
        data.put("Status" , 0);
        JSONObject request = new JSONObject();
        request.put("request", data);
        logger.info("申请单关闭请求json->" + request.toJSONString());

        String respStr = "";
        try {
            respStr = Request.Post(SmeCtripConstants.SETAPPROVAL_ACTION_URL)
                    .bodyString(request.toJSONString(), ContentType.APPLICATION_JSON)
                    .connectTimeout(60000).socketTimeout(60000)
                    .execute().returnContent().asString(Charset.forName("UTF-8"));
        } catch (Exception e) {
            res.put("success", false);
            res.put("msg", "推送携程商旅通失败 IO异常:" + e.getStackTrace());
            result.add(res);
            return result;
        }
        JSONObject respJson = JSONObject.parseObject(respStr);
        res.put("success", false);
        if (respJson != null) {
            JSONObject resultJson = respJson.getJSONObject("SetApprovalResult");
            JSONObject statusJson = resultJson.getJSONObject("Status");
            if (!statusJson.getBoolean("Success")) {
                String message = statusJson.getString("Message");
                logger.error("sme申请单关闭失败->" + message);
                res.put("msg", "sme申请单关闭失败->" + message);
            } else {
                res.put("success", true);
                logger.info("携程商旅通申请单关闭成功");
            }
        }
        result.add(res);
        return result;
    }

    /**
     * 申请单数据处理
     *
     * @param applyOrderJson 申请单信息
     * @param tenant         租户ID
     * @param channel        渠道
     * @return 携程申请单信息
     */
    private JSONObject processApplyData(JSONObject applyOrderJson, String tenant, BriChannel channel) {
        JSONObject applyData = new JSONObject();

        JSONObject nodeBusinessTrip = applyOrderJson;
        JSONObject special = nodeBusinessTrip.getJSONObject("special");
        String openType = special.getString("openType");

        if (StringUtil.isNotEmpty(nodeBusinessTrip.getString("billNum"))) {
            applyData.put("ApprovalNumber", nodeBusinessTrip.getString("billNum"));
        } else {
            applyData.put("ApprovalNumber", special.getString("applayNumber"));
        }
        applyData.put("Status", 1);
        //        员工ID
        String userId = nodeBusinessTrip.getString("userId");
        List<String> list = new ArrayList<>();
        list.add(userId);
        List<UcUserDto> users = iUserCenterService.getCompleteUcUserDtoByUserid(list, tenant);
        if (!CollectionUtils.isEmpty(users)) {
            if ("".equals(users.get(0).getPersonCode())) {
                applyData.put("EmployeeID", userId);
            } else {
                applyData.put("EmployeeID", users.get(0).getPersonCode());
            }
        } else {
            applyData.put("msg", "找不到用户:" + userId);
            return applyData;
        }
        JSONObject config = JSON.parseObject(channel.getConfig());
        JSONObject authentification = new JSONObject();
        authentification.put("AppKey", config.getString("appKey"));
        try {
            authentification.put("Ticket", getSetApprovalTicket(channel));
        } catch (Exception e) {
            logger.error("携程商旅通获取ticket失败. " + e.getStackTrace());
            applyData.put("msg", "携程商旅通获取ticket失败. " + e.getStackTrace());
            return applyData;
        }
        applyData.put("Auth", authentification);

        // 审批单过期时间
        Calendar c = Calendar.getInstance();
        if (nodeBusinessTrip.getDate("endDate") != null) {
            c.setTime(nodeBusinessTrip.getDate("endDate"));
            c.add(Calendar.DAY_OF_MONTH, 1);
            Format f = new SimpleDateFormat("yyyy-MM-dd");
            Date expiredTime = c.getTime();
            applyData.put("ExpiredTime", f.format(expiredTime));
        }

        //费用承担信息
        processCostInfo(tenant, userId, openType, applyData, channel, nodeBusinessTrip);


        logger.info("携程商旅通同步申请单-1.单号=" + applyData.getString("ApprovalNumber") +
                ",过期时间=" + applyData.getString("ExpiredTime"));

        //飞机信息
        JSONArray flightEndorsementDetails = null;
        //火车信息
        JSONArray trainEndorsementDetails = null;
        //住宿
        JSONArray hotelEndorsementDetails = null;
        // 单据详情
        JSONArray travelList = nodeBusinessTrip.getJSONArray("nodeBusinessTravelList");

        if (null != travelList && travelList.size() > 0) {
            flightEndorsementDetails = getFlightInfos(travelList, nodeBusinessTrip, users.get(0), tenant, openType);
            trainEndorsementDetails = getTrainInfos(travelList, nodeBusinessTrip, users.get(0), tenant, openType);
            hotelEndorsementDetails = getHotelInfos(travelList, nodeBusinessTrip, users.get(0), tenant, openType);
        }
        if (flightEndorsementDetails != null && flightEndorsementDetails.size() > 0) {
            applyData.put("FlightEndorsementDetails", flightEndorsementDetails);
        }
        if (trainEndorsementDetails != null && trainEndorsementDetails.size() > 0) {
            applyData.put("TrainEndorsementDetails", trainEndorsementDetails);
        }

        if (hotelEndorsementDetails != null && hotelEndorsementDetails.size() > 0) {
            applyData.put("HotelEndorsementDetails", hotelEndorsementDetails);
        }
        if (CollectionUtils.isEmpty(flightEndorsementDetails) && CollectionUtils.isEmpty(trainEndorsementDetails) && CollectionUtils.isEmpty(hotelEndorsementDetails)) {
            logger.error("向携程商旅通推送数据:飞机、火车、酒店数据为空、推送数据失败！");
            applyData.put("msg", "向携程商旅通推送数据:飞机、火车、酒店数据为空、推送数据失败！");
            applyData.put("needUpdate", true);
            return applyData;
        }
        return applyData;
    }


    /**
     * 同步费用归属信息
     * @param tenant
     * @param userId
     * @param openType
     * @param applyData
     * @param channel
     * @param nodeBusinessTrip
     */
    private void processCostInfo(String tenant, String userId, String openType, JSONObject applyData, BriChannel channel, JSONObject nodeBusinessTrip) {
        if (channel != null && channel.getSyncCostInfo() != 0) {
            //费用承担部门
            String assumeDept = nodeBusinessTrip.getString("assumeDept");
            String[] assumeDeptArr = assumeDept != null ? assumeDept.split(",") : null;

            //费用承担单位
            String assumeOrg = nodeBusinessTrip.getString("assumeOrg");
            String[] assumeOrgArr = assumeOrg != null ? assumeOrg.split(",") : null;

            //费用项目
            String costProject = nodeBusinessTrip.getString("costProject");
            String[] costProjectArr = costProject != null ? costProject.split(",") : null;

            String assumeDeptValue = "";
            String assumeOrgValue = "";
            String assumeProjectValue = "";
            switch (channel.getSyncCostInfo()) {
                //传名称
                case 1:
                    if (assumeDeptArr != null && assumeDeptArr.length > 0){
                        if (assumeDeptArr.length > 1){
                            assumeDeptValue = assumeDeptArr[1];

                        }else {
                            Map<String, String> deptInfo = baseDocService.getDeptByOsType(tenant, userId ,assumeDeptArr[0], openType);
                            assumeDeptValue = deptInfo != null ? deptInfo.get("name") : "";
                        }
                    }

                    if (assumeOrgArr != null && assumeOrgArr.length > 0){
                        if (assumeOrgArr.length > 1){
                            assumeOrgValue = assumeOrgArr[1];
                        }else {
                            Map<String, String> orgInfo = baseDocService.getOrgByOsType(tenant, userId, assumeOrgArr[0], openType);
                            assumeOrgValue = orgInfo != null ? orgInfo.get("name") : "";
                        }
                    }

                    if (costProjectArr != null && costProjectArr.length > 0){
                        if (costProjectArr.length > 1){
                            assumeProjectValue = costProjectArr[1];
                        }else {
                            Map<String, String> projectInfo = baseDocService.getInOutProjectByOsType(tenant, userId, costProjectArr[0], openType);
                            assumeProjectValue = projectInfo != null ? projectInfo.get("name") : "";
                        }
                    }
                    break;
                //传pk
                case 2:
                    if (assumeDeptArr != null && assumeDeptArr.length > 0){
                        assumeDeptValue = assumeDeptArr[0];
                    }

                    if (assumeOrgArr != null && assumeOrgArr.length > 0){
                        assumeOrgValue = assumeOrgArr[0];
                    }

                    if (costProjectArr != null && costProjectArr.length > 0){
                        assumeProjectValue = costProjectArr[0];
                    }
                    break;
                default:
                    break;
            }

            ArrayList<ExtendField> extendFields = new ArrayList<>();

            if (assumeOrgArr != null && assumeOrgArr.length > 0) {
                ExtendField orgField = new ExtendField();
                orgField.setFieldName("CostCenter1");
                orgField.setFieldType("String");
                orgField.setFieldValue(assumeOrgValue);
                extendFields.add(orgField);
            }

            if (assumeDeptArr != null && assumeDeptArr.length > 0) {
                ExtendField deptField = new ExtendField();
                deptField.setFieldName("CostCenter2");
                deptField.setFieldType("String");
                deptField.setFieldValue(assumeDeptValue);
                extendFields.add(deptField);
            }
            if (costProjectArr != null && costProjectArr.length > 0) {
                ExtendField projectField = new ExtendField();
                projectField.setFieldName("CostCenter2");
                projectField.setFieldType("String");
                projectField.setFieldValue(assumeProjectValue);
                extendFields.add(projectField);

            }

            if (extendFields.size() > 0) {
                applyData.put("ExtendFieldList", extendFields);
            }
        }
    }


    /**
     * 机票信息拼装
     *
     * @param travelList       申请单行程明细
     * @param nodeBusinessTrip 申请单信息
     * @param sscUser         申请人
     * @return 携程申请单机票信息
     */
    private JSONArray getFlightInfos(JSONArray travelList, JSONObject nodeBusinessTrip, UcUserDto sscUser, String tenant, String openType) {
        JSONArray flightEndorsementDetails = new JSONArray();
        logger.info("向携程商旅通推送数据:组织飞机数据！");
        JSONObject flightEndorsementDetail = new JSONObject();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (nodeBusinessTrip.getDate("startDate") == null) {
            logger.info("携程的出发日期为空");
        } else {
            // 出发日期
            flightEndorsementDetail.put("DepartDateBegin", simpleDateFormat.format(nodeBusinessTrip.getDate("startDate")));
            flightEndorsementDetail.put("ReturnDateBegin", simpleDateFormat.format(nodeBusinessTrip.getDate("startDate")));
        }
        if (nodeBusinessTrip.getDate("endDate") == null) {
            logger.info("携程的结束日期为空");
        } else {
            // 到达日期
            flightEndorsementDetail.put("DepartDateEnd", simpleDateFormat.format(nodeBusinessTrip.getDate("endDate")));
        }
        // 出发城市
        ArrayList<String> fromCitesList = new ArrayList<String>();
        // 到达城市
        ArrayList<String> toCitesList = new ArrayList<String>();
        //出行人详情
        JSONArray passengerDetailArray = new JSONArray();
        getPassenger(nodeBusinessTrip, passengerDetailArray, sscUser, tenant, openType);


        // 预定类型 国内
        flightEndorsementDetail.put("ProductType", 1);
        flightEndorsementDetail.put("FlightWay", 1);
        for (int i = 0; i < travelList.size(); i++) {
            JSONObject travel = travelList.getJSONObject(i);
            if (null != travel.getString("tripWay") && "飞机".equals(travel.getString("tripWay"))) {
                if (StringUtil.isNotEmpty(travel.getString("fromCity"))) {
                    fromCitesList.add(travel.getString("fromCity").split("-")[0]);
                } else {
                    logger.info("向携程商旅通推送数据错误：单据明细数据主键=" + travel.getString("pk") + ",飞机出发城市不能为空！");
                    continue;
                }
                if (StringUtil.isNotEmpty(travel.getString("toCity"))) {
                    toCitesList.add(travel.getString("toCity").split("-")[0]);
                } else {
                    logger.info("向携程商旅通推送数据错误：单据明细数据主键=" + travel.getString("pk") + ",飞机到达城市不能为空！");
                    continue;
                }
                if (null != travel.getString("tripType") && "RT".equals(travel.getString("tripType"))) {

                    flightEndorsementDetail.put("FlightWay", 2);
                } else {
                    if (!"2".equals(String.valueOf(flightEndorsementDetail.get("FlightWay")))) {
                        flightEndorsementDetail.put("FlightWay", 1);
                    }
                }
            }
        }
        flightEndorsementDetail.put("FromCities", fromCitesList);
        flightEndorsementDetail.put("ToCities", toCitesList);
        flightEndorsementDetail.put("PassengerList", passengerDetailArray);
        if (fromCitesList.size() > 0 && toCitesList.size() > 0) {
            flightEndorsementDetails.add(flightEndorsementDetail);
        }
        return flightEndorsementDetails;
    }

    private void getPassenger(JSONObject nodeBusinessTrip, JSONArray passengerDetailArray, UcUserDto sscUser, String tenant, String openType) {
        String passengers = nodeBusinessTrip.getString("actualPedestrian");
        if (StringUtil.isNotEmpty(passengers)) {
            passengers = passengers.replace("，", ",")
                    .replace("、", ",").replace("/", ",")
                    .replace("。", ",").replace(" ", "").trim();
            String[] split = passengers.split(";");
            List<String> persionIds = new ArrayList<>();
            for (String str : split) {
                if (str.split(",").length > 0) {
                    persionIds.add(str.split(",")[0]);
                }
            }
            List<UcUserDto> companionUser = null;
            if ("nc".equals(openType)) {
                companionUser = iUserCenterService.getCompleteUcUserByPersonIds(persionIds, tenant);
            } else {
                companionUser = iUserCenterService.getCompleteUcUserDtoByUserid(persionIds, tenant);
            }
            if (companionUser != null && companionUser.size() > 0) {
                for (UcUserDto ucUserDto : companionUser) {
                    JSONObject passengerDetail = new JSONObject();
                    passengerDetail.put("Name", ucUserDto.getUserName());
                    passengerDetailArray.add(passengerDetail);
                }
            } else {
                logger.info("用户中心未找到实际出行人:" + persionIds.toString());
                //TODO 用户中心未找到人员时同步erp用户，再次查找。
                throw new BusinessException("用户中心未找到部分实际出行人");
            }
        }
        // 旧的实际出行人为手输格式，支持格式  张三,李四
        String companion = nodeBusinessTrip.getString("companion");
        //如果手输实际出行人和制单人名字一致，则忽略
        if (StringUtils.isNotEmpty(companion) && !companion.equals(sscUser.getUserName())) {
            companion = convertTraveler(companion);
            companion = companion.replaceAll("，", ",").replaceAll("、", ",").replaceAll("/", ",").replaceAll("。", ",").replaceAll(" ", "").trim();
            String[] splitCompanion = companion.split(",");
            for (String oneCompanion : splitCompanion) {
                if(StringUtils.isNotBlank(oneCompanion)){
                    String[] strings = oneCompanion.split(":");
                    JSONObject passengerDetail = new JSONObject();
                    passengerDetail.put("Name", strings[0]);
                    passengerDetailArray.add(passengerDetail);
                }
            }
        }
        if (passengerDetailArray.size() == 0) {
            JSONObject passengerDetail = new JSONObject();
            passengerDetail.put("Name", sscUser.getUserName());
            passengerDetailArray.add(passengerDetail);
        }
    }

    /**
     * 转换companion中的字符
     * @param companion
     * @return
     */
    public static String convertTraveler(String companion){
        String convertStr = companion;
        if (companion.contains("（")){
            convertStr = companion.replaceAll("（",",");
        }
        if (companion.contains("(")){
            convertStr = convertStr.replaceAll("\\(",",");
        }
        if (companion.contains("）")){
            convertStr = convertStr.replaceAll("）","");
        }
        if (companion.contains(")")){
            convertStr = convertStr.replaceAll("\\)","");
        }
        if (companion.contains("，")){
            convertStr = convertStr.replaceAll("，",",");
        }
        if (companion.contains("、")){
            convertStr = convertStr.replaceAll("、",",");
        }
        return convertStr;
    }
    /**
     * 火车票信息拼装
     *
     * @param travelList       申请单行程明细
     * @param nodeBusinessTrip 申请单信息
     * @param sscUser         申请人
     * @return 携程申请单火车票信息
     */
    private JSONArray getTrainInfos(JSONArray travelList, JSONObject nodeBusinessTrip, UcUserDto sscUser, String tenant, String openType) {
        logger.info("向携程商旅通推送数据:组织火车数据！");
        JSONArray trainEndorsementDetails = new JSONArray();
        JSONObject trainEndorsementDetail = new JSONObject();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (nodeBusinessTrip.getDate("startDate") == null) {
            logger.info("携程的出发日期为空");
        } else {
            // 出发日期
            trainEndorsementDetail.put("DepartDateBegin", simpleDateFormat.format(nodeBusinessTrip.getDate("startDate")));
        }
        if (nodeBusinessTrip.getDate("endDate") == null) {
            logger.info("携程的结束日期为空");
        } else {
            // 到达日期
            trainEndorsementDetail.put("DepartDateEnd", simpleDateFormat.format(nodeBusinessTrip.getDate("endDate")));
        }
        // 出发城市
        ArrayList<String> fromCitesList = new ArrayList<String>();
        // 到达城市
        ArrayList<String> toCitesList = new ArrayList<String>();
        //出行人详情
        JSONArray passengerDetailArray = new JSONArray();
        // 出行人列表
        getPassenger(nodeBusinessTrip, passengerDetailArray, sscUser, tenant, openType);

        // 预定类型 国内
        trainEndorsementDetail.put("ProductType", "5");
        trainEndorsementDetail.put("TripType", "1");
        for (int i = 0; i < travelList.size(); i++) {
            JSONObject travel = travelList.getJSONObject(i);
            if (null != travel.getString("tripWay") && "火车".equals(travel.getString("tripWay"))) {
                if (StringUtil.isNotEmpty(travel.getString("fromCity"))) {
                    fromCitesList.add(travel.getString("fromCity").split("-")[0]);
                } else {
                    logger.info("向携程商旅通推送数据错误：单据明细数据主键=" + travel.getString("pk") + ",火车出发城市不能为空！");
                    continue;
                }
                if (StringUtil.isNotEmpty(travel.getString("toCity"))) {
                    toCitesList.add(travel.getString("toCity").split("-")[0]);
                } else {
                    logger.info("向携程商旅通推送数据错误：单据明细数据主键=" + travel.getString("pk") + ",火车到达城市不能为空！");
                    continue;
                }
                if (null != travel.getString("tripType") && "RT".equals(travel.getString("tripType"))) {
                    trainEndorsementDetail.put("TripType", "2");
                } else {

                    if (!"2".equals(String.valueOf(trainEndorsementDetail.get("TripType")))) {
                        trainEndorsementDetail.put("TripType", "1");
                    }
                }
            }
        }
        trainEndorsementDetail.put("FromCities", fromCitesList);
        trainEndorsementDetail.put("ToCities", toCitesList);
        trainEndorsementDetail.put("PassengerList", passengerDetailArray);
        if (fromCitesList.size() > 0 && toCitesList.size() > 0) {
            trainEndorsementDetails.add(trainEndorsementDetail);
        }
        return trainEndorsementDetails;
    }

    /**
     * 酒店信息拼装
     *
     * @param travelList       申请单行程明细
     * @param nodeBusinessTrip 申请单信息
     * @param sscUser         申请人
     * @return 携程申请单酒店信息
     */
    private JSONArray getHotelInfos(JSONArray travelList, JSONObject nodeBusinessTrip, UcUserDto sscUser, String tenant, String openType) {
        logger.info("向携程商旅通推送数据:组织住宿数据！");
        JSONArray hotelEndorsementDetails = new JSONArray();
        JSONObject hotelEndorsementDetail = new JSONObject();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (nodeBusinessTrip.getDate("startDate") == null) {
            logger.info("携程的出发日期为空");
        } else {
            // 出发日期
            hotelEndorsementDetail.put("CheckInDateBegin", simpleDateFormat.format(nodeBusinessTrip.getDate("startDate")));
        }
        if (nodeBusinessTrip.getDate("endDate") == null) {
            logger.info("携程的结束日期为空");
        } else {
            // 到达日期
            hotelEndorsementDetail.put("CheckInDateEnd", simpleDateFormat.format(nodeBusinessTrip.getDate("endDate")));
        }
        // 城市
        ArrayList<String> toCitesList;
        //实际出行人
        JSONArray passengerDetailArray = new JSONArray();
        getPassenger(nodeBusinessTrip, passengerDetailArray, sscUser, tenant, openType);

        // 预定类型 国内
        hotelEndorsementDetail.put("ProductType", "3");
        for (int i = 0; i < travelList.size(); i++) {
            JSONObject travel = travelList.getJSONObject(i);
            if (null != travel.getBigDecimal("yghotelcost") && travel.getBigDecimal("yghotelcost").compareTo(new BigDecimal(0)) > 0) {
                toCitesList = new ArrayList<>();
                //酒店入住城市不传
                hotelEndorsementDetail.put("ToCities", toCitesList);
                hotelEndorsementDetail.put("PassengerList", passengerDetailArray);
                if (travel.getBigDecimal("hotelstandard") != null && travel.getBigDecimal("hotelstandard").doubleValue() > 0) {
                    hotelEndorsementDetail.put("AveragePrice", travel.getBigDecimal("hotelstandard").doubleValue());
                }
                hotelEndorsementDetails.add(hotelEndorsementDetail);
                break;
            }
        }
        return hotelEndorsementDetails;
    }
}